package com.yitao.cms.service.exchangeRate;

import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.skipper.base.bean.CommonStatus;
import com.skipper.base.bean.DataOutput;
import com.skipper.base.bean.PagedInput;
import com.skipper.base.bean.PagedOutput;
import com.skipper.base.data.querydsl.PredicateBuilder;
import com.skipper.base.json.JSONObject;
import com.skipper.base.service.GenericEntityService;
import com.yitao.client.constant.ExchangeRateEnum;
import com.yitao.client.dto.exchangerate.ExchangeRateDto;
import com.yitao.client.model.exchangerate.ExchangeRateModel;
import com.yitao.client.model.exchangerate.QExchangeRateModel;
import com.yitao.cms.constant.intergenix.IntergenixConstant;
import com.yitao.cms.utils.BaseUtils;
import com.yitao.cms.utils.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Date: 2019/9/18 14:38
 * @Author: Kien
 */
@Service
public class ExchangeRateService extends GenericEntityService<ExchangeRateModel, ExchangeRateDto, QExchangeRateModel> {
    private BaseUtils base = BaseUtils.getInstance();

    public ExchangeRateService(EntityManager entityManager) {
        super(entityManager);
    }

    /**
     *
     * 功能描述: 新增汇率
     * @param sourceCurrency 兑换货币
     * @param targetCurrency 目标货币
     * @param exchangeRate 汇率
     * @param bankReleaseTime 发布时间
     * @param issueBank 发布银行
     *
     * @param
     * @return
     * @auther: Kien
     * @date: 2019/9/18 15:13
     */
    @Transactional
    public DataOutput saveExchangeRate(String sourceCurrency, String targetCurrency, String exchangeRate, String bankReleaseTime, String issueBank) {
        ExchangeRateModel exchangeRateModel = new ExchangeRateModel();
        if(base.parametersIsBlank(sourceCurrency, targetCurrency, exchangeRate, bankReleaseTime, issueBank)) {
            logger.info("有参数为空{sourceCurrency: " + sourceCurrency + ", targetCurrency: "
                    + targetCurrency + ", exchangeRate: " + exchangeRate + ", bankReleaseTime: " + bankReleaseTime + ", issueBank: " + issueBank + "}");
            return new DataOutput(CommonStatus.BAD_REQUEST);
        }
        Date date = new Date();
        // 为了保证一天只有一条数据，如果按兑换货币和目标货币查询，存在执行update操作
        List<ExchangeRateModel> all = repository.findAll(PredicateBuilder.conjunction()
                .and(() -> Q.targetCurrency.eq(targetCurrency))
                .and(() -> Q.sourceCurrency.eq(sourceCurrency))
                .and(() -> Q.createTime.between(DateUtils.getDayStartTime(date), DateUtils.getDayEndTime(date)))
                .get());
        if(CollectionUtils.isEmpty(all)) {
            logger.info("不存在当日汇率，新增");
            exchangeRateModel.setSourceCurrency(sourceCurrency); // 兑换货币
            exchangeRateModel.setTargetCurrency(targetCurrency); // 目标货币
            exchangeRateModel.setBankReleaseTime(DateUtils.parseDateMilliFormat(bankReleaseTime)); // 银行发布时间
            exchangeRateModel.setCreateBy(-1L); // 景逸默认给-1
            exchangeRateModel.setCreateTime(new Date());
            exchangeRateModel.setExchangeRate(exchangeRate); // 汇率
            exchangeRateModel.setIssueBank(issueBank); // 发布银行
            exchangeRateModel.setIsDelete(false);
            ExchangeRateModel save = repository.save(exchangeRateModel);
            if(save != null) {
                return new DataOutput();
            }
        } else {
            logger.info("已存在当日汇率，更新");
            int i = repository.updateByWhere(PredicateBuilder.conjunction()
                    .and(() -> Q.targetCurrency.eq(targetCurrency))
                    .and(() -> Q.sourceCurrency.eq(sourceCurrency))
                    .and(() -> Q.createTime.between(DateUtils.getDayStartTime(date), DateUtils.getDayEndTime(date)))
                    .get(), it -> {
                it.set(Q.bankReleaseTime, DateUtils.parseDateMilliFormat(bankReleaseTime));
                it.set(Q.exchangeRate, exchangeRate);
                it.set(Q.createBy, -1L);
            });
            if(i != 0) {
                return new DataOutput();
            }
        }
        return new DataOutput(CommonStatus.SERVER_ERROR);
    }

    /**
     *
     * 功能描述: 查询汇率
     *
     * @param sourceCurrency 源货币
     * @param targetCurrency 目标货币
     * @param pageNo
     * @param pageSize
     * @return
     * @auther: Kien
     * @date: 2019/9/18 15:57
     */
    public PagedOutput<ExchangeRateDto> findExchangeRate(String sourceCurrency, String targetCurrency, Integer pageNo, Integer pageSize) {
        PagedInput pagedInput = new PagedInput(pageSize, pageNo);
        if(base.parametersIsBlank(sourceCurrency, targetCurrency)) {
            return new PagedOutput(CommonStatus.BAD_REQUEST, pagedInput, 0, new ArrayList());
        }
        String sourceCurrencyName = ExchangeRateEnum.CURRENCY_ABBREVIATION.getNameByAbbreviation(sourceCurrency); // 源货币中文名称
        String targetCurrencyName = ExchangeRateEnum.CURRENCY_ABBREVIATION.getNameByAbbreviation(targetCurrency); // 目标货币中文名称
        PagedOutput<ExchangeRateModel> pagedOutput = repository.pagingList(PredicateBuilder.conjunction()
                .and(() -> Q.targetCurrency.eq(targetCurrency))
                .and(() -> Q.sourceCurrency.eq(sourceCurrency))
                .and(() -> Q.isDelete.eq(false))
                .get(), pagedInput, new OrderSpecifier<>(Order.DESC, Q.bankReleaseTime));
        List<ExchangeRateDto> list = new ArrayList<>();
        if(pagedOutput != null && pagedOutput.getData() != null && pagedOutput.getData().size() != 0) {
            list = pagedOutput.getData().stream().map(it -> {
                ExchangeRateDto exchangeRateDto = new ExchangeRateDto();
                base.convertEntityToDto(it, exchangeRateDto);
                exchangeRateDto.setBankReleaseTimeString(DateUtils.getDateFormat(exchangeRateDto.getBankReleaseTime(), "yyyy-MM-dd")); // 发布时间
                exchangeRateDto.setSourceCurrency(sourceCurrencyName); // 源货币名称
                exchangeRateDto.setTargetCurrency(targetCurrencyName); // 目标货币名称
                exchangeRateDto.setIssueBank(ExchangeRateEnum.BANK_ABBREVIATION.getNameByAbbreviation(it.getIssueBank())); // 发布银行名称
                return exchangeRateDto;
            }).collect(Collectors.toList());
        }
        return new PagedOutput(pagedInput, pagedOutput.getTotalElements(), list);
    }

    /**
     * 功能描述: 返回最新的一条汇率
     *
     * @param sourceCurrency 需要查询的币种
     *
     * @return
     * @auther Kien
     * @date 2019/12/5 11:48
     */
    public JSONObject findNewExchangeRate(String sourceCurrency) {
        JSONObject jsonObject = new JSONObject();
        if(StringUtils.isEmpty(sourceCurrency)) {
            logger.info("币种代码为空");
            jsonObject.put("status", IntergenixConstant.JsonEnmu.ERROR.getStatus()); // 失败
            jsonObject.put("result", null);
            return jsonObject;
        }
        logger.info("供应链获取最新的一条汇率");
        List<ExchangeRateModel> fetch = queryFactory.select(Q).from(Q)
                .where(PredicateBuilder.conjunction()
                        .and(() -> Q.isDelete.eq(false))
                        .and(() -> Q.sourceCurrency.eq(sourceCurrency))
                        .get())
                .orderBy(new OrderSpecifier<>(Order.DESC, Q.bankReleaseTime)).offset(0).limit(1).fetch();
        if(CollectionUtils.isEmpty(fetch)) {
            logger.info("未获取到汇率数据");
            jsonObject.put("status", IntergenixConstant.JsonEnmu.ERROR.getStatus()); // 失败
            return jsonObject;
        }
        jsonObject.put("status", IntergenixConstant.JsonEnmu.SUCCESS.getStatus()); // 成功
        jsonObject.put("result", convertEntityToDto(fetch.get(0)));
        return jsonObject;
    }
}
